/**
 * 2017年3月21日
 */
package cn.edu.bjtu.alex.rewrite.components;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

import cn.edu.bjtu.alex.rewrite.Context;
import cn.edu.bjtu.alex.rewrite.tools.NamedThreadFactory;

/**
 * @author Alex
 *
 */
public class Stat extends BaseComponent implements Iterator<Entry<String,Integer>>{
	private ExecutorService executorService;
	CountDownLatch latch;
	AtomicLong al = new AtomicLong(0);
	
	//label numofDocs
	Map<String,Integer> eachLabelCount = new ConcurrentHashMap<String,Integer>();
	Iterator<Entry<String,Integer>> it = null;
	public long getTotalDoc(){
		return al.get();
	}
	
	public Stat(Context ctx) {
		super(ctx);
	}
	
	public void fitInternal() {
		File dir = ctx.getInputDir();
		//类文件夹 名字如果没改的话一般是c1 c2 c3等
		File []dirs = dir.listFiles(new FileFilter() {
			public boolean accept(File pathname) {
				return pathname.isDirectory();
			}
		});
		int numClsses = dirs.length;
		latch = new CountDownLatch(numClsses); 
		executorService = Executors.newCachedThreadPool(new NamedThreadFactory("Stat-Thread"));
		for(File f : dirs){
			String label = f.getName();
			LOG.info("Add label: label=" + label);
			executorService.submit(new EachLabelWordAnalysisWorker(f.getName()));
		}
		try {
			latch.await();
			executorService.shutdown();
		} catch (InterruptedException e) {e.printStackTrace();}
		it = this.eachLabelCount.entrySet().iterator();
		
	}
	//一个线程去搜集一个文件下的文档
	private final class EachLabelWordAnalysisWorker extends Thread {
		
		private final String label;
		private final Context ctx;
		private Integer lineNum = 0;
		public EachLabelWordAnalysisWorker(String label) {
			this.label = label;
			this.ctx = Stat.this.ctx;
		}

		@Override
		public void run() {
			try {
				File labelDir = new File(Stat.this.ctx.getInputDir(), label);
				File[] files = labelDir.listFiles(new FileFilter() {
					public boolean accept(File pathname) {
						return pathname.getAbsolutePath().endsWith(ctx.getFileExtensionName());
					}
				});
				if(files==null || files.length==0){
					eachLabelCount.put(label, 0);
					return ;
				}
				int n = 0;
				for(File file : files) {
					analyze(label, file);
					++n;
				}
			} finally {
				latch.countDown();
			}
		}
		protected void analyze(String label, File file) {
			BufferedReader br = null;
			try{
				br = new BufferedReader(new FileReader(file));
				while(( br.readLine())!=null){lineNum ++ ;}
				eachLabelCount.put(label, lineNum);
				al.getAndAdd(lineNum);
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				try {br.close();} catch (IOException e) {}
			}
			
		}
	}

	@Override
	protected void transformInternal() {}

	public boolean hasNext() {
		return this.it == null?false:(it.hasNext());
	}

	@Override
	public Entry<String, Integer> next() {
		return it.next();
	}

}
